package com.gitee.wsl.doc.prosemirror.model.node.ext

import com.gitee.wsl.doc.prosemirror.model.node.Node
import com.gitee.wsl.doc.prosemirror.model.node.NodeBase


// Check whether splitting at the given position is allowed.
fun Node.canSplit( pos: Int, depth: Int = 1, typesAfter: List<NodeBase?>? = null): Boolean {
    val doc = this
    val resolvedPos = doc.resolve(pos)
    val base = resolvedPos.depth - depth
    val innerType = typesAfter?.lastOrNull() ?: resolvedPos.parent
    if (base < 0 || resolvedPos.parent.type.spec.isolating == true ||
        !resolvedPos.parent.canReplace(resolvedPos.index(), resolvedPos.parent.childCount) ||
        !innerType.type.validContent(
            resolvedPos.parent.content.cutByIndex(resolvedPos.index(), resolvedPos.parent.childCount)
        )
    ) {
        return false
    }
    var d = resolvedPos.depth - 1
    var i = depth - 2
    while (d > base) {
        val node = resolvedPos.node(d)
        val index = resolvedPos.index(d)
        if (node.type.spec.isolating == true) return false
        var rest = node.content.cutByIndex(index, node.childCount)
        val overrideChild = typesAfter?.get(i + 1)
        if (overrideChild != null) {
            rest = rest.replaceChild(0, overrideChild.type.create(overrideChild.attrs))
        }
        val after = typesAfter?.get(i) ?: node
        if (after != node) rest = rest.replaceChild(0, after.type.create(after.attrs))
        if (!node.canReplace(index + 1, node.childCount) || !after.type.validContent(rest)) {
            return false
        }
        d--
        i--
    }
    val index = resolvedPos.indexAfter(base)
    val baseType = typesAfter?.firstOrNull()
    return resolvedPos.node(base).canReplaceWith(index, index, baseType?.type ?: resolvedPos.node(base + 1).type)
}
